import {Injectable} from '@angular/core';
import {HttpClient} from '@angular/common/http';
import {Observable, Subject} from 'rxjs';
import {AuthService} from "../../services/auth.service";
import {ConfigService} from "../../services/config.service";
import {Product} from "../../model/product/entity/product";
import {map} from "rxjs/operators";
import {ProductConfig} from "../../model/product-config";
import * as moment from "moment";

@Injectable({
  providedIn: 'root'
})
export class ProductService {

    private baseUrl = this.configService.api.url + '/products';  // URL to web API
    private subject: any = {
        create: new Subject<any>(),
        delete: new Subject<any>(),
        update: new Subject<any>(),
        refresh: new Subject<any>()
    };

    constructor(private http: HttpClient, private authService: AuthService, private configService: ConfigService) {
    }

    on(event, callback) {
        return this.subject[event].subscribe(value => callback(value));
    }

    emit(event, value: any) {
        return this.subject[event].next(value);
    }

    create(product: Product): Observable<any> {
        let headers = this.authService.getHeader();
        let options = {headers: headers};
        product.create();
        return this.http.post(this.baseUrl + '/create', {product: product.toJSON()}, options);
    }

    delete(id: string): Observable<any> {
        let headers = this.authService.getHeader();
        let options = {headers: headers};
        return this.http.post(this.baseUrl + '/' + id + '/remove', options);
    }

    update(product: Product): Observable<any> {
        let headers = this.authService.getHeader();
        let options = {headers: headers};
        return this.http.post(this.baseUrl + '/' + product._id + '/update', {product: product.toJSON()}, options);
    }

    getAll(): Observable<any> {
        let headers = this.authService.getHeader();
        let options = {headers: headers};
        return this.http.get(this.baseUrl + '/', options).pipe(map( (res:any) => {
            return res.map(item => {
                const product = new Product();
                product.fromJSON(item);
                product.relate(ProductConfig.getInstance());
                return product;
            });
        }));
    }

    getOne(id: string): Observable<any> {
        let headers = this.authService.getHeader();
        let options = {headers: headers};
        return this.http.get(this.baseUrl + '/detail/' + id, options).pipe(map(item => {
            const product = new Product();
            product.fromJSON(item);
            product.relate(ProductConfig.getInstance());
            return product;
        }));
    }

    getByCode(code: string): Observable<any> {
        let headers = this.authService.getHeader();
        let options = {headers: headers};
        return this.http.get(this.baseUrl + '/code/' + code, options).pipe(map(item => {
            const product = new Product();
            product.fromJSON(item);
            product.relate(ProductConfig.getInstance());
            return product;
        }));
    }

}
